#!/bin/bash
# USAGE:
#	scenes 
#	scenes exclude orbitFolder1 orbitFolder2 ...
#	scenes include orbitFolder1 orbitFolder2 ...
#	scenes init /path/to/data [/path/to/output/data/folder/]
#       scenes add /path/to/data 
#	scenes rescan
#
# DESCRIPTION:
#  SCENES is an internal ADORE command. 
#  It has the following usages: 
#
#  scenes: 
#   	With no input parameters all available scenes are shown.
#
#  scenes exclude:
# 	With no inputs this command lists currently excluded scenes.
#
#  scenes exclude orbitFolder1 orbitFolder2 ...:
#       listed orbit folders (folders inside data folder) are excluded from
#       batch processing.
#
# scenes include:
#  	With no inputs this command lists currently included scenes. 
#
# scenes include orbitFolder1 orbitFolder2 ...:
#  	given orbit folders will be removed from the exclude list. 
#
# scenes init /path/to/data/folder [/path/to/output/data/folder/]:
#	Initializes the $dataFolder and creates links to data files stored in 
#       the path to data folder. Output data folder is by default the 
#       $dataFolder variable. Keep in mind that the dataFolder will be set
#       to the newly created output data folder.  
#
# scenes rename [date,datetime,orbit,trackframe,bistatic]:
#	rename scenes in the data folder given the naming convention.
#
# scenes rescan: 
#	rescan the $dataFolder and reset the included scenes
#
# 

function all_scenes(){
  ls -F ${dataFolder}/ 2>/dev/null| grep "/"| tr -d "/"
}

function find_scenes(){
  scene=${1}
  shift
  array=( ${@} )
  for (( k=0; k<${#array[@]}; k++ ))
  do 
    if [ "${array[k]}" == "${scene}" ]; then
      echo ${k}
      return
    else
      continue
    fi
  done
  echo -1  
}

function sort_scenes(){
  echo ${@}|tr ' ' "\n"|uniq|sort
}

function scenes_exclude(){
  if [ "${1:-undefined}" == "undefined" ];then
    if [ ${#scenes_exclude[@]} -gt 0 ]; then
    #if [ -n "${scenes_exclude}" ]; then
      #echo ${scenes_exclude}
      echo ${scenes_exclude[@]}
    else 
      error "Currently, no scenes are excluded."
    fi
  else
    local scene scene_location
    for scene in "$@"
    do
      if [ -d "${dataFolder}/${scene}" ]; then
        #echo "Excluding ${scene}"
        #echo "${orbit}" >> ${excludesFile}
#        scenes_exclude=`echo ${scenes_exclude} ${scene} | tr " " "\n"|sort|tr "\n" " "`;
#        scenes_include="${scenes_include//${scene}/}"; # Remove the given string from includes, add it to the excludes.
 	scenes_exclude=( ${scenes_exclude[@]} ${scene} );
 	#scenes_include=( ${scenes_include[@]//${scene}/} );
 	scene_location=`find_scenes ${scene} "${scenes_include[@]}"`
 	[ ${scene_location} -gt -1 ] && scenes_include=( ${scenes_include[@]:0:$scene_location} ${scenes_include[@]:$(($scene_location + 1))} )
      else
        error "Can not find ${scene} in data folder: ${dataFolder}"
        return;
      fi
    done
  fi
  scenes_exclude=( $(sort_scenes ${scenes_exclude[@]}))
}

function scenes_include(){
  if [ "${1:-undefined}" == "undefined" ]; then
    if [ ${#scenes_include[@]} -gt 0 ]; then
    #if [ -n "${scenes_include}" ]; then
#      echo ${scenes_include}
      echo ${scenes_include[@]}
    else
      error "Currently, there are no scenes included. Check if you have your dataFolder set correctly."  
    fi
  else    
    local scene scene_location
    for scene in "$@"  
    do
#      scenes_exclude="${scenes_exclude[@]//${scene}/}"; # Remove the given string from excludes, add it to the includes.
#      scenes_include=`echo ${scenes_include[@]} ${scene} |tr " " "\n"|sort|tr "\n" " "`;
      if [ -d "${dataFolder}/${scene}" ]; then
#        scenes_exclude=( ${scenes_exclude[@]//${scene}/} );
  	scene_location=`find_scenes ${scene} "${scenes_exclude[@]}"`
  	[ ${scene_location} -gt -1 ] && scenes_include=( ${scenes_exclude[@]:0:$scene_location} ${scenes_exclude[@]:$(($scene_location + 1))} )
        scenes_include=( ${scenes_include[@]} ${scene} );
      fi
    done
  fi
}

function detectSatellite(){
#Modified from
# STAMPS3.2/link_slcs:goodSense(), Mahmut Arikan - 20091021 
local DATADIR="${1}"
  #local firstDATADIR=`canonicalPath "${DATADIR}/*"| head -n 1`
  echo "I can detect: ERS1/2, ASAR, TSX, TDX, CSK1-4, GAMMA, and ADORE SLC images for now."
  echo "If you are using other datasets please setup the dataFolder manually."
  m_in_method='UNKNOWN'
  #if $( ls -1 ${firstDATADIR}/CSK*.h5 &> /dev/null ); then
  if [ $( find -L "${DATADIR}" -maxdepth 2 -name "CSK*.h5" 2> /dev/null | wc -l ) -gt 0 ]; then 
    m_in_method='CSK';
    dataFile="CSK*.h5"
  #elif $( ls -1 ${firstDATADIR}/T*.xml &>/dev/null ); then
  elif [ $( find -L "${DATADIR}" -maxdepth 3 -name "T*.xml" 2> /dev/null | wc -l ) -gt 0 ]; then
    m_in_method='TSX'
    dataFile="*.cos"
    leaderFile="T*.xml"
  #elif $( ls -1 ${firstDATADIR}/*slc.par &>/dev/null ); then
  elif [ $( find -L "${DATADIR}" -maxdepth 2 -name "*slc.par" 2> /dev/null | wc -l ) -gt 0 ]; then
    m_in_method="GAMMA"
    dataFile="*slc"
    leaderFile="p*slc.par"
    volumeFile="System.par"
    echo "Please verify patterns for dataFile, leaderFile and volumeFile."
    getInfoFromUser "${DATADIR}"
  #elif $( ls -1 ${firstDATADIR}/ASA* &>/dev/null ); then
  elif [ $( find -L "${DATADIR}" -maxdepth 2 -name "ASA*" 2> /dev/null | wc -l ) -gt 0 ]; then
    m_in_method='ASAR'    
    dataFile="ASA*.N1"
  #elif $( ls -1 ${firstDATADIR}/*001 &>/dev/null ); then
  elif [ $( find -L "${DATADIR}" -maxdepth 2 -name "*001" 2> /dev/null | wc -l ) -gt 0 ]; then
    m_in_method='ERS'
    dataFile="DAT_01.001"
    leaderFile="LEA_01.001"
    volumeFile="VDF_DAT.001"
    nullFile="NUL_01.001"
  #elif $( ls -1 ${firstDATADIR}/*H1.1__A &>/dev/null ); then
  elif [ $( find -L "${DATADIR}" -maxdepth 2 -name "*H1.1__A" 2> /dev/null | wc -l ) -gt 0 ]; then
    m_in_method="ALOS"
    dataFile="IMG*H1.1__A"
    leaderFile="LED*H1.1__A" 
    volumeFile="VOL*H1.1__A" 
    nullFile="TRL*H1.1__A"
  elif [ $( find -L "${DATADIR}" -maxdepth 2 -name "*.res" 2> /dev/null | wc -l ) -gt 0 ]; then
    m_in_method="ADORE"
    slcType="ADORE"
    dataFile="*.crop"
    leaderFile="*.res"
  else 
    error "I could not define the image type."
    getInfoFromUser "${DATADIR}"    
  fi  
}

function setSlcRes(){
  if [ "${m_in_method}" == "ERS" ]; then
    slc_az_res=`grep "^ERS" "${ADOREFOLDER}/set/resolution.csv" | cut -f4 -d","`
    slc_rg_res=`grep "^ERS" "${ADOREFOLDER}/set/resolution.csv" | cut -f3 -d","`
  elif [ "${m_in_method}" == "ASAR" ]; then
    slc_az_res=`grep "^ASAR,Stripmap" "${ADOREFOLDER}/set/resolution.csv" | cut -f4 -d","`
    slc_rg_res=`grep "^ASAR,Stripmap" "${ADOREFOLDER}/set/resolution.csv" | cut -f3 -d","`
  elif [ "${m_in_method}" == "GAMMA" ]; then
    slc_az_res=`grep "^azimuth_resolution" "${m_in_lea}" | tr -s "[:blank:]" ","| cut -f2 -d","`
    slc_rg_res=`grep "^range_resolution" "${m_in_lea}" | tr -s "[:blank:]" ","| cut -f2 -d","`
    slc_az_res=`echo "${slc_az_res}" | awk '{printf("%d\n",$0+=$0<0?-0.5:0.5)}'`    
    slc_rg_res=`echo "${slc_rg_res}" | awk '{printf("%d\n",$0+=$0<0?-0.5:0.5)}'`
  elif [ "${m_in_method}" == "ADORE" ]; then
    #settings apply -r ${q} master=${master} slave=${slave}
    local masterLeaderFile="${dataFolder}/${master}/${leaderFile}"
    local productType=`readRes.sh ${masterLeaderFile} readfiles "Product type specifier"`;
    m_in_method=`productType2m_in_method ${productType}`
    setSlcRes
    m_in_method="ADORE" 
  else 
    echo "I am unable to detect the imaging mode for ${m_in_method}."
    echo "I have the following information in my database which may help you [mode,az,rg]:"
    grep "^${m_in_method}" "${ADOREFOLDER}/set/resolution.csv"
    #echo "Please enter azimuth resolution in meters:"
    #read slc_az_res
    #echo "Please enter range resolution in meters:"
    #read slc_rg_res
    echo "Please enter range and azimuth resolution separated by comma(,) [az,rg]:"
    read slc_az_rg_res
    slc_az_res=${slc_az_rg_res%%,*};
    slc_rg_res=${slc_az_rg_res##*,};
  fi
  echo "SLC resolution set to [az,rg]: ${slc_az_res} ${slc_rg_res}"
}

function getInfoFromUser(){
  local DATADIR="${1}"
  bold "What is the m_in_method? Available options are: ERS, ASAR, RSAT, RADARSAT-2, ATLANTIS, JERS, ALOS, TSX, CSK, GAMMA"
  echo "Current setting: [${m_in_method}]"
  read userInput
  [ -n "${userInput}" ] && settings apply -r ${q} m_in_method="${userInput}"      

  bold "Please indicate which sub-folder contains a SAR image."
  echo "Here is the listing of the directory you provided:"
  ls "${DATADIR}"
  read firstScene
  firstDATADIR="${DATADIR}/${firstScene}"
  
  bold "What is the dataFile pattern? [${dataFile}]"
  echo "Here is the listing of the files in the first data folder."
  ls "${firstDATADIR}"
  read userInput
  [ -n "${userInput}" ] && settings apply -r ${q} dataFile="${userInput}"

  echo "Leader, volume and null files may be necessary for ${m_in_method} data."
  if ask "Do you also want to enter the patterns for leader, volume and null files?"
  then

    bold "What is the leaderFile pattern? [${leaderFile}]"
    read userInput
    [ -n "${userInput}" ] && settings apply -r ${q} leaderFile="${userInput}"
    bold "What is the volumeFile pattern? [${volumeFile}]"
    read userInput
    [ -n "${userInput}" ] && settings apply -r ${q} volumeFile="${userInput}"
    bold "What is the nullFile pattern? [${nullFile}]"
    read userInput
    [ -n "${userInput}" ] && settings apply -r ${q} nullFile="${userInput}"
  fi  
}

function linkADORE(){
local DATADIR=${1}
  for f in $(find -L "${DATADIR}" -name "${dataFile}"); do
    dname=$( dirname ${f} )
    date=`grep "First_pixel_azimuth_time" ${f} |tr -s "\t" " " | cut -d " " -f 3`
    if [ -z "${date}" ]; then
      date=$(basename ${dname})
    else
      date=`date -d "${date}" +%Y%m%d`
    fi
    mkdir -p ${dataFolder}/${date}
    ln -s ${dname}/${leaderFile} ${dataFolder}/${date}/
    ln -s ${dname}/${dataFile} ${dataFolder}/${date}/
  done
}

function linkERS(){
#Modified from
# STAMPS3.2/link_slcs:goodERS(), Mahmut Arikan - 20091021 
local DATADIR=${1}
local date
  #for f in $(ls -1d ${DATADIR}/*); do
  for f in $(find -L "${DATADIR}" -name "${dataFile}"); do
    #echo info: $f
    #date=$( awk '/ORBIT/{print substr($5,1,8)}' ${f}/L* )
    dname=$( dirname ${f} )
    date=`awk '/ORBIT/{print substr($5,1,8)}' ${dname}/${leaderFile}`
    mkdir -p ${dataFolder}/${date}
    ln -s ${dname}/${leaderFile} ${dataFolder}/${date}/
    ln -s ${dname}/${dataFile} ${dataFolder}/${date}/
    ln -s ${dname}/${volumeFile} ${dataFolder}/${date}/
    ln -s ${dname}/${nullFile} ${dataFolder}/${date}/
  done
}

function linkASAR(){
#get list of files
local rawDataFolder=$1
local file folderName absFilePath

for file in $(find -L "${rawDataFolder}" -name "${dataFile}")
do
  #folderName=`echo $file|cut -c23-30`
  folderName=`envisat_dump_header ${file} | awk '/^ABS_ORBIT /{printf "%s",$3}'`
  absFilePath=`canonicalPath ${file}`
  mkdir -p ${dataFolder}/${folderName} # create folder if missing
  ln -s "${absFilePath}" ${dataFolder}/${folderName}/
done
}

function linkTSX(){
#Modified from
# STAMPS3.2/link_slcs:goodTSX(), Mahmut Arikan - 20091021 
local DATADIR=${1}
local f bname date tsxdir cosfile cosbname 
  for f in $(find -L "${DATADIR}" -name "${leaderFile}"); do
    #echo info: $f
    bname=$( basename ${f} )
    #date=`echo $bname | awk -F '_' {'print substr($13,1,8)'}` #This line fails for a name like: TDX1_SAR__SSC_BRX2_SM_S_SRA_20110629T105154_20110629T105157.xml
    date=`echo $bname |cut -c 29-36`
    tsxdir=${f%/*}
    cosfile=`find -L $tsxdir -name "*.cos"` 
    cosbname=$( basename ${cosfile} )
    if [ -d "${dataFolder}/${date}" ]; then 
      #switch to full name TSXYYYYMMDDTHHMMSS or TDX...
      sat=`echo $bname |cut -c 1-3`
      date=`echo $bname |cut -c 29-43`
      date="${sat}${date}"
      if [ -d "${dataFolder}/${date}" ]; then
        error "Can not add already existing data: ${f}"
        continue
      fi
    fi    
    mkdir -p ${dataFolder}/${date}
    ln -s ${f} ${dataFolder}/${date}                 # xml
    #ln -s ${bname} leader.xml ${dataFolder}/${date}/  # xml
    ln -s ${cosfile} ${dataFolder}/${date}
    #ln -s ${cosbname} image.slc
  done
}

function linkALOS(){
#Modified from
# linkERS
local DATADIR=${1}
local date
  #for f in $(ls -1d ${DATADIR}/*); do
  for fd in $(find -L "${DATADIR}" -name "${dataFile}"); do
    f=`dirname "${fd}"`
    #echo info: $f
    #date=$( awk '/ORBIT/{print substr($5,1,8)}' ${f}/L* )
    if [ -d "${f}" ]; then 
      date=`awk '/ALPSRP/{print substr($4,1,8)}' ${f}/${leaderFile}`
      if [ $? -eq 0 ]; then 
        mkdir -p ${dataFolder}/${date}
        ln -s ${f}/${leaderFile} ${dataFolder}/${date}/
        ln -s ${f}/${dataFile} ${dataFolder}/${date}/
        ln -s ${f}/${volumeFile} ${dataFolder}/${date}/
        ln -s ${f}/${nullFile} ${dataFolder}/${date}/
      fi
    fi
  done
}

function linkGAMMA(){
#Modified from
# linkALOS
local DATADIR=${1}
local date
  #for f in $(ls -1d ${DATADIR}/*); do
  for fl in $(find -L "${DATADIR}" -name "${dataFile}"); do
    #echo info: $f
    #date=$( awk '/ORBIT/{print substr($5,1,8)}' ${f}/L* )
    local f=`dirname ${fl}`
    #if [ -d "${f}" ]; then 
    date=`awk '/date:/{printf "%4d%02d%02d",$2, $3, $4}' ${f}/${leaderFile}`
    if [ $? -eq 0 ]; then 
      if [ -d "${dataFolder}/${date}" ]; then 
        error "Can not add already existing data: ${f}"
        continue
      fi
      mkdir -p ${dataFolder}/${date}
      ln -s ${f}/${leaderFile} ${dataFolder}/${date}/
      ln -s ${f}/${dataFile} ${dataFolder}/${date}/
      ln -s ${f}/${volumeFile} ${dataFolder}/${date}/
      ln -s ${f}/${nullFile} ${dataFolder}/${date}/
    else
      error "Can not add ${fd}. Not a GAMMA focused SLC?"
    fi
    #fi
  done
}

function linkCSK(){
#Modified from
# STAMPS3.2/link_slcs:goodTSX(), Mahmut Arikan - 20091021 
local DATADIR="${1}"
local f bname date 
  for f in $(find -L "${DATADIR}" -name "${dataFile}"); do
    #echo info: $f
    bname=$( basename "${f}" )
    date=`echo "$bname" | awk -F '_' {'print substr($9,1,8)'}`

    if [ -d "${dataFolder}/${date}" ]; then 
      #is the file already in dataFolder (is it the same file?)
      diff ${dataFolder}/${date}/${bname} ${f} 
      if [ $? -eq 0 ]; then
        error "Skipping existing data: ${f}"
        continue
      else      
        date=`echo "$bname" | awk -F '_' {'print substr($9,1,16)'}`
        if [ -d "${dataFolder}/${date}" ]; then 
          error "Can not add already existing data: ${f}"
          continue
        fi
      fi
    fi
    mkdir -p "${dataFolder}/${date}"
    ln -s "${f}" "${dataFolder}/${date}"                 # h5
  done
}

function scenes_init(){
if [ "${1:-isEmpty}" == "isEmpty" ]; then
  error "Scenes init requires one parameter"
  error "  Usage: scenes init /path/to/data/folder"
  return
fi
if [ "${2:-isEmpty}" != "isEmpty" ]; then
  settings apply dataFolder="${2}" #do not do -r because it will revert to $projectFolder/data
fi
echo "Using dataFolder=${dataFolder}"
local rawDataFolder=`canonicalPath "${1}"`
local batchOn=${batch}
batch="off"

mkdir -p "${dataFolder}"
detectSatellite "${rawDataFolder}"; #sets m_in_method
case "${m_in_method}" in
ERS)
  linkERS "${rawDataFolder}";
  ;;
ASAR)
  linkASAR "${rawDataFolder}";
  ;;
TSX)
  linkTSX "${rawDataFolder}";  
  ;;
ALOS)
  linkALOS "${rawDataFolder}";
  ;;
GAMMA)
  linkGAMMA "${rawDataFolder}";
  ;;
CSK)
  linkCSK "${rawDataFolder}";
  ;;
ADORE)
  linkADORE "${rawDataFolder}";
  ;;
esac

[ -z "${master}"	] && master=`ls -F ${dataFolder}/ 2>/dev/null |grep "/" | head -n 1|tr -d "/"|tr -d [:blank:] |tr -d "\n" 2>/dev/null`
[ -z "${slave}"        	] && slave=`ls -F ${dataFolder}/  2>/dev/null | grep "/" | awk 'NR==2' | tr -d "/"| tr -d [:blank:] | tr -d "\n" 2>/dev/null`
settings apply -r -q master=${master} slave=${slave}

#### set slc_az_res and slc_rg_res
setSlcRes 
batch="${batchOn}"
}

function scenes_add(){
local f
for f in "${@}"
do 
  local rawDataFolder=`canonicalPath "${f}"`
  #detectSatellite "${rawDataFolder}"; #sets m_in_method
  case "${m_in_method}" in
  ERS)
    linkERS "${rawDataFolder}";
    ;;
  ASAR)
    linkASAR "${rawDataFolder}";
    ;;
  TSX)
    linkTSX "${rawDataFolder}";  
    ;;
  ALOS)
    linkALOS "${rawDataFolder}";
    ;;
  GAMMA)
    linkGAMMA "${rawDataFolder}";
    ;;
  CSK)    
    linkCSK "${rawDataFolder}";
    ;;
  ADORE)
    linkADORE "${rawDataFolder}";
    ;;
  esac
done
}

function scenes_rename(){
 local newname bname
 for f in `scenes include`
 do 
   case "${1}" in
   datetime)
     if [ "${m_in_method}" == "CSK" ]; then
       bname=$( basename ${dataFolder}/${f}/${dataFile} )
       newname=`echo "$bname" | awk -F '_' {'print substr($9,1,16)'}`
       if [ "${newname}" != "${f}" ]; then 
         echo "Renaming: ${f}  as ${newname}"
         mv ${dataFolder}/${f} ${dataFolder}/${newname}
       fi
     fi
   ;;
   bistatic)
     if [ "${m_in_method}" == "TSX" ]; then
       bname=$( basename ${dataFolder}/${f}/${leaderFile} )
       newname="${bname:28:8}${bname:15:2}"
       if [ "${newname}" != "${f}" ]; then
         echo "Renaming: ${f}  as ${newname}"
         mv ${dataFolder}/${f} ${dataFolder}/${newname}
       else
         error "Can not rename ${f}. ${newname} exists."
       fi
     fi
   ;;
   esac
 done
 scenes rescan
}

function scenes_rescan(){
  scenes_include=( `ls -F "${dataFolder}/"  2>/dev/null | grep "/" | tr -d "/"` )  
  local se=(${scenes_exclude[@]})
  scenes_exclude=( )
  [ ${#se[@]} -gt 0 ] && scenes_exclude ${se[@]}
  scenes_exclude=( $(sort_scenes ${scenes_exclude[@]}))
  scenes_include=( $(sort_scenes ${scenes_include[@]}))
  
}

function productType2m_in_method(){
  local productType=${1}
  case ${productType} in 
  TSX*)
    echo "TSX"
  ;;
  TDX*)
    echo "TSX"
  ;;
  *IS*)
    echo "ASAR"
  ;;
  CSK*)
    echo "CSK"
  ;;
  *)
    echo "${productType}"
  esac
}

case "${1}" in 
"")
 all_scenes
 ;;
"exclude")
 shift
 scenes_exclude "$@"
 ;;
"include")
 shift
 scenes_include "$@"
 ;;
"init")
 shift
 scenes_init "$@"
 scenes_rescan
 ;;
"rename")
 shift
 scenes_rename "$@"
 ;;
"rescan")
 shift
 scenes_rescan
 ;;
"add")
 shift
 scenes_add "${@}"
 scenes_rescan
 ;;
esac

